package com.wz.boot.core;


import com.wz.boot.annotation.Handle;
import com.wz.boot.function.defaultchat.DefaultChat;
import com.wz.boot.pojo.ClassProperty;
import love.forte.simbot.annotation.OnPrivate;
import love.forte.simbot.api.message.MessageContentBuilderFactory;
import love.forte.simbot.api.message.events.PrivateMsg;
import love.forte.simbot.api.sender.Sender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 核心功能类：用于转发消息到功能类
 */
@Component
public class PrivateMsgForwardCore {

    private static Logger logger = LoggerFactory.getLogger(PrivateMsgForwardCore.class);

    @Autowired
    private MessageContentBuilderFactory messageContentBuilderFactory;

    @Autowired
    DefaultChat defaultChat;

    //功能记录的集合
    private List<ClassProperty> classPropertyList = new ArrayList<>();

    //简易功能介绍文本
    private String simpleFunctionText = null;

    //全部功能介绍文本
    private String allFunctionText = null;

    //用户当前所在的位置  key:qqAccount value: position
    private Map<String,Integer> privatePersonCurrentPositionMap = new HashMap<>();


    /**
     * 从MyInit类中加载扫描出来的配置
     */
    public void loadVariableFromMyInit(){

        classPropertyList = ProjectFunctionScanAndInitCore.getClassPropertyList();
        simpleFunctionText = ProjectFunctionScanAndInitCore.getSimpleFunctionText();
        allFunctionText = ProjectFunctionScanAndInitCore.getAllFunctionText();

    }


    /**
     * 此处进行统一拦截，并转发到各个功能类中
     * @param privateMsg
     * @param sender
     */
    @OnPrivate
    public void onPrivate(PrivateMsg privateMsg, Sender sender) {
        //得到初始信息
        String msg = privateMsg.getMsgContent().getMsg();
        String account = privateMsg.getAccountInfo().getAccountCode();
        String nickname = privateMsg.getAccountInfo().getAccountNickname();
        logger.info("{}:{} 发来了： {} ", account, nickname, msg);
        //拦截指定命令-功能查询
        if("功能查询".equals(msg) || "fs".equalsIgnoreCase(msg)){
            sender.sendPrivateMsg(privateMsg,simpleFunctionText);
            logger.info("向{}:{} 发送了： {} ", account, nickname, simpleFunctionText);
            return;
        }
        //拦截指定命令-完整功能查询
        if("完整功能查询".equals(msg) || "all".equalsIgnoreCase(msg)){
            sender.sendPrivateMsg(privateMsg,allFunctionText);
            logger.info("向{}:{} 发送了： {} ", account, nickname, allFunctionText);
            return;
        }
        //拦截exit指令-exit
        if("退出".equals(msg)){
            //得到当前的位置
            Integer currentPosition = privatePersonCurrentPositionMap.get(account);//代指优先级
            if(currentPosition == -1 || currentPosition == null){
                //当前没有在具体功能中
                String text = "您已经在顶级菜单中啦~ 输入[功能查询]或[fs]查询功能列表;\n输入[完整功能查询]或[all]查询完整功能列表";
                sender.sendPrivateMsg(privateMsg,text);
                return;
            }
            for (ClassProperty classProperty : classPropertyList) {
                int claPriority = classProperty.getPriority();//这个priority就是position, 其数值一样，含义不一样罢了
                if(currentPosition == claPriority){
                    Object object = classProperty.getObject();
                    Method exitMethod = classProperty.getExitMethod();
                    if(exitMethod != null) {
                        try {
                            exitMethod.invoke(object, privateMsg, sender);
                            logger.info("{} 退出了功能: {}", account, classProperty.getName());
                        } catch (Exception e) {
                            logger.error("执行invoke出错  {} 原因:{}", e.getMessage(), e.getCause());
                        }
                    }
                    String text = "您已退到顶级菜单, 输入[功能查询]或[fs]查询功能列表\n输入[完整功能查询]或[all]查询完整功能列表";
                    sender.sendPrivateMsg(privateMsg, text);
                    logger.info("向{}:{} 发送了： {} ", account, nickname, text);
                    //-1代表跟此人聊过天, 但是没有选择菜单,
                    privatePersonCurrentPositionMap.put(account,-1);
                    return;
                }
            }
        }
        //判断此人是否在顶级菜单
        if(!privatePersonCurrentPositionMap.containsKey(account)){
            // -1 代表跟此人聊过天, 但是没有选择菜单,
            privatePersonCurrentPositionMap.put(account,-1);
            sender.sendPrivateMsg(privateMsg,simpleFunctionText);
            logger.info("向{}:{} 发送了功能菜单： {} ", account, nickname, simpleFunctionText);
            return;
        }
        //如果已给这个人发生过功能菜单，但是对方没有选择功能
        if(privatePersonCurrentPositionMap.get(account).equals(-1)){
            for (ClassProperty classProperty : classPropertyList) {
                //看看是否选择了某项菜单
                if(classProperty.getTouch().equals(msg)){
                    privatePersonCurrentPositionMap.put(account, classProperty.getPriority());
                    //提示对方进入了功能菜单中
                    sender.sendPrivateMsg(privateMsg,"您已进入功能: "+classProperty.getName());
                    logger.info("{}:{} 进入功能：{}  {}  ", account, nickname, classProperty.getClaName(), classProperty.getName());
                    return;
                }

            }
            //开启闲聊模式，调用闲聊模式的代码快  默认优先级为0
            defaultChat.aiChat(privateMsg,sender);
            return;
        }
        //对方已经选择了具体的功能，调用功能函数-利用反射的方法
        int currentPosition = privatePersonCurrentPositionMap.get(account);
        for (ClassProperty classProperty : classPropertyList) {
            if(classProperty.getPriority() == currentPosition){
                Object cla = classProperty.getObject();
                //是否使用了指定的handle处理器
                boolean tag = false;
                List<Method> methodList = classProperty.getMethodList();
                for (Method method : methodList) {
                    Handle handle = method.getDeclaredAnnotation(Handle.class);
                    if(handle.touch().equals(msg)){
                        try {
                            tag = true;
                            logger.info("向{}:{} 调用{}.{}", account, nickname,classProperty.getClaName(),method.getName());
                            method.invoke(cla,privateMsg,sender);
                            return;
                        } catch (Exception e) {
                            logger.error(e.getMessage()+" ---->原因："+e.getCause());
                            e.printStackTrace();
                        }
                    }
                }
                if(!tag){
                    Method defaultMethod = classProperty.getDefaultMethod();
                    try {
                        logger.info("向{}:{} 调用默认{}  handle", account, nickname,msg);
                        defaultMethod.invoke(cla,privateMsg,sender);
                        return;
                    } catch (Exception e) {
                        logger.error(e.getMessage()+" ---->原因："+e.getCause());
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
